package com.yxsk.relay.job.component.common.net;

import lombok.extern.slf4j.Slf4j;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class NettyServer implements NetServer {

    public static final int DEFAULT_LISTEN_PORT = 8071;

    // 服务监听端口，缺省端口 8071
    private int listenPort;
    private ServerBootstrap bootstrap;
    private ChannelPipelineFactory pipelineFactory;

    public NettyServer(ChannelPipelineFactory pipelineFactory) {
        this(pipelineFactory, DEFAULT_LISTEN_PORT);
    }

    public NettyServer(ChannelPipelineFactory pipelineFactory, int listenPort) {
        if (pipelineFactory == null) {
            throw new IllegalArgumentException("Pipeline factory not be null.");
        }
        if (listenPort <= 0) {
            throw new IllegalArgumentException("Listen port error[" + listenPort + "]");
        }
        this.pipelineFactory = pipelineFactory;
        this.listenPort = listenPort;
    }

    public void start() {
        this.bootstrap = new ServerBootstrap();
        this.bootstrap.setPipelineFactory(this.pipelineFactory);
        if (log.isDebugEnabled()) {
            log.debug("Initialize channel successfully. Channel pipeline: {}", this.pipelineFactory.getClass().getSimpleName());
        }

        if (log.isInfoEnabled()) {
            log.info("Bind netty server listen port: {}", this.listenPort);
        }
        ExecutorService bossPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        ExecutorService workerPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
        this.bootstrap.setFactory(new NioServerSocketChannelFactory(bossPool, workerPool));
        this.bootstrap.bind(new InetSocketAddress(this.listenPort));

        if (log.isInfoEnabled()) {
            log.info("Netty server start success");
        }
    }

    public void stop() {
        if (this.bootstrap == null) {
            throw new IllegalStateException("Netty server is null.");
        }

        this.bootstrap.shutdown();

        if (log.isInfoEnabled()) {
            log.info("Netty server closed.");
        }
    }

    @Override
    public void pause() throws UnsupportedOperationException {
        throw new UnsupportedOperationException("Unsupported pause.");
    }

}
